package com.ruoyi.web.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.jfinal.kit.StrKit;
import com.ruoyi.common.business.entity.YytMember;
import com.ruoyi.common.business.service.YytMemberService;
import com.ruoyi.common.oms.entity.YytOmsOrder;
import com.ruoyi.common.oms.service.YytOmsOrderService;
import com.ruoyi.common.pms.entity.YytPmsSkuInfo;
import com.ruoyi.common.pms.entity.YytPmsSpuInfo;
import com.ruoyi.common.pms.service.YytPmsSkuInfoService;
import com.ruoyi.common.pms.service.YytPmsSpuInfoService;
import com.ruoyi.common.vip.entity.PayPlaceAnOrderEntity;
import com.ruoyi.common.vip.entity.YytVipMember;
import com.ruoyi.common.vip.entity.YytVipType;
import com.ruoyi.common.vip.service.YytVipMemberService;
import com.ruoyi.common.vip.service.YytVipTypeService;
import com.ruoyi.utils.ResponseResult;
import com.ruoyi.utils.SnowflakeIdWorker;
import com.ruoyi.vo.VipAddMemberVo;
import com.ruoyi.vo.VipIsSelectDateVo;
import com.ruoyi.vo.WxPayBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author MrPing
 * @since 2022-07-14
 */
@RestController
@RequestMapping("/vip")
public class YytVipTypeController extends AbstractWxPayApiController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private YytVipTypeService yytVipTypeService;

    @Autowired
    private YytVipMemberService yytVipMemberService;

    @Autowired
    private YytMemberService yytMemberService;

    @Autowired
    private YytOmsOrderService yytOmsOrderService;

    @Autowired
    private YytPmsSkuInfoService yytPmsSkuInfoService;

    @Autowired
    private YytPmsSpuInfoService yytPmsSpuInfoService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    private String notifyUrl;
    private String refundNotifyUrl;

    @Autowired
    private WxPayBean wxPayBean;

    @Override
    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            System.out.println("wxPayBean.getCertPath():" + wxPayBean.getCertPath());
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        notifyUrl = apiConfig.getDomain().concat("/order/payNotify");
//        refundNotifyUrl = apiConfig.getDomain().concat("/order/refundNotify");
        return apiConfig;
    }

    /**
     * 获取年卡类型
     * @return
     */
    @GetMapping("/getVipList")
    public ResponseResult getVipList(){
        return ResponseResult.success(yytVipTypeService.list());
    }

    /**
     * 获取雪花id
     * @return
     */
    @GetMapping("/getSnowflakeID")
    public ResponseResult getSnowflakeID() {
        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0);
        long id = idWorker.nextId();
        return ResponseResult.success(id);
    }

    /**
     * 微信小程序支付(年卡充值)
     */
    @RequestMapping(value = "/miniAppPay", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public ResponseResult miniAppPay(@RequestBody PayPlaceAnOrderEntity payPlaceAnOrderEntity, HttpServletRequest request) {
        //需要通过授权来获取openId
        String openId = payPlaceAnOrderEntity.getOpenId();

        String ip = IpKit.getRealIp(request);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        WxPayApiConfigKit.putApiConfig(getApiConfig());
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();

        // TODO 充值测试金额
        payPlaceAnOrderEntity.setTotal_fee(1000000);
        // 正式金额
//        payPlaceAnOrderEntity.setTotal_fee(payPlaceAnOrderEntity.getTotal_fee() * 100);

        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId()) // 小程序ID
                .mch_id(wxPayApiConfig.getMchId()) // 商户号
                .nonce_str(WxPayKit.generateStr()) // 随机字符串
                .body(payPlaceAnOrderEntity.getBody()) // 商品描述
                .attach("农博园商城") // 附加数据
                .out_trade_no(payPlaceAnOrderEntity.getOut_trade_no()) // 商户订单号


                .total_fee(payPlaceAnOrderEntity.getTotal_fee().toString()) // 标价金额
                .notify_url(notifyUrl) // 通知地址(回调地址)
                .spbill_create_ip(ip) // 终端IP
                .trade_type(TradeType.JSAPI.getTradeType()) // 交易类型
                .openid(openId) // 用户标识
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);

        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return ResponseResult.failure(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return ResponseResult.failure(returnMsg);
        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");
        Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
        String jsonStr = JSON.toJSONString(packageParams);
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        log.info("小程序支付的参数:" + jsonObject);
        return ResponseResult.success(jsonObject);
    }

    /**
     * 充值记录
     * @param vipAddMemberVo
     * @return
     */
    @PostMapping("/addVipMember")
    @Transactional
    public ResponseResult addVipMember(@RequestBody VipAddMemberVo vipAddMemberVo){
        YytVipMember yytVipMember = new YytVipMember();
        LocalDateTime dateTime = null;
        // 获取会员类型
        YytVipType vipType = yytVipTypeService.getById(vipAddMemberVo.getVipTypeId());
        yytVipMember.setTopUpOrder(vipAddMemberVo.getTopUpOrder());
        yytVipMember.setMemberId(vipAddMemberVo.getMemberId());
        yytVipMember.setVipTypeId(vipAddMemberVo.getVipTypeId());
        yytVipMember.setPrice(vipAddMemberVo.getPrice());
        yytVipMember.setCreateTime(LocalDateTime.now());


        // 获取用户是续费还是充值
        YytMember member = yytMemberService.getById(vipAddMemberVo.getMemberId());
        QueryWrapper<YytVipMember> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("member_id", vipAddMemberVo.getMemberId()).eq("vip_end_time", member.getVipEndTime()).eq("status", "1");
        YytVipMember one = yytVipMemberService.getOne(wrapper1, false);
        if(one != null){
            // 剩余次数加上新增加的次数
            yytVipMember.setGreensNumber(vipType.getSendGreenNumber() + one.getGreensNumber());

            UpdateWrapper<YytVipMember> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", one.getId()).set("greens_number", 0).set("status", "0");
            yytVipMemberService.update(updateWrapper);

            Date endDate = Date.from(member.getVipEndTime().atZone(ZoneId.systemDefault()).toInstant());
            Calendar cal = Calendar.getInstance();
            cal.setTime(endDate);
            cal.add(cal.MONDAY, vipAddMemberVo.getDeadline());
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
            Date calTime = cal.getTime();
            dateTime = calTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            System.out.println(dateTime);
            yytVipMember.setVipEndTime(dateTime);
        }else{

            yytVipMember.setGreensNumber(vipType.getSendGreenNumber());
            // 获取明天开始时间
            Calendar cal = Calendar.getInstance();
            cal.add(cal.MONDAY, vipAddMemberVo.getDeadline());
            cal.add(cal.DATE, 1);
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
            Date calTime = cal.getTime();
            dateTime = calTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            System.out.println(dateTime);
            yytVipMember.setVipEndTime(dateTime);
        }

        // 插入到会员充值表
        boolean b = yytVipMemberService.save(yytVipMember);

        // 把会员截止时间放入消息延时推送
        if (b){
            // 修改年卡购买记录
            UpdateWrapper<YytVipType> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", vipAddMemberVo.getVipTypeId()).setSql("cart_number = cart_number + 1");
            yytVipTypeService.update(updateWrapper);

            // 修改用户会员状态
            UpdateWrapper<YytMember> wrapper = new UpdateWrapper<>();
            wrapper.eq("id", yytVipMember.getMemberId()).set("is_vip", "1").set("vip_end_time", dateTime);
            yytMemberService.update(wrapper);

//            // 把会员结束时间放入倒计时
//            long endNumber = dateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
//            long validNum =  new Date().getTime();
//            BigInteger bigintA = new BigInteger(endNumber + "");
//            BigInteger bigintB = new BigInteger(validNum + "");
//            long longValue = bigintA.subtract(bigintB).longValue();
//
//
//            log.info("过期倒计时值: {}", longValue);
//            rabbitTemplate.convertAndSend("xinjunDelayedVipExchange","delayedVipEndKey", vipAddMemberVo.getMemberId(), message -> {
//                message.getMessageProperties().setHeader("x-delay", String.valueOf(longValue));
//                return message;
//            });
        }

        return ResponseResult.success(b);
    }


    /**
     * 获取我开通的会员类型
     * @return
     */
    @GetMapping("/getMyVipInfo")
    public ResponseResult getMyVipInfo(@RequestParam("memberId") String memberId){

        YytMember member = yytMemberService.getById(memberId);
        QueryWrapper<YytVipMember> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id", memberId).eq("vip_end_time", member.getVipEndTime()).eq("status", "1");
        YytVipMember one = yytVipMemberService.getOne(wrapper, false);
        if(one == null){
            return ResponseResult.success();
        }
        return ResponseResult.success(yytVipTypeService.getById(one.getVipTypeId()));
    }

    /**
     * 获取我的剩余次数
     */
    @GetMapping("/getMyNumber")
    public ResponseResult getMyNumber(@RequestParam("memberId") String memberId){
        YytMember member = yytMemberService.getById(memberId);
        QueryWrapper<YytVipMember> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id", memberId).eq("vip_end_time", member.getVipEndTime()).eq("status", "1");
        YytVipMember one = yytVipMemberService.getOne(wrapper, false);
        return ResponseResult.success(one);
    }


    /**
     * 获取用户是否可以选菜
     * @param memberId
     * @return
     */
    @GetMapping("/getUserIsSelect")
    public ResponseResult getUserIsSelect(@RequestParam("memberId") String memberId){
        QueryWrapper<YytVipMember> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id", memberId).gt("greens_number", 0).eq("status", 1);
        List<YytVipMember> vipMembers = yytVipMemberService.list(wrapper);
        if(vipMembers.size() > 0){
            return ResponseResult.success(true);
        }
        return ResponseResult.success(false);
    }


    /**
     * 该会员本周是否已经选过菜
     * @return
     */
    @PostMapping("/getIsPassSelect")
    public ResponseResult getIsPassSelect(@RequestBody VipIsSelectDateVo dateVo){
        QueryWrapper<YytOmsOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id", dateVo.getMemberId()).eq("order_type", "1").in("delivery_date", dateVo.getDateList());
        List<YytOmsOrder> list = yytOmsOrderService.list(wrapper);
        return ResponseResult.success(list.size() > 0);
    }


    /**
     * 会员菜品
     * @return
     */
    @GetMapping("/getVipGreens")
    public ResponseResult getVipGreens(){
        QueryWrapper<YytPmsSpuInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("spu_add_type", 3).eq("publish_status", 1);
        List<YytPmsSpuInfo> spuInfos = yytPmsSpuInfoService.list(wrapper);
        List<String> list = new ArrayList<>();
        for (YytPmsSpuInfo yps : spuInfos){
            list.add(yps.getId());
        }
        QueryWrapper<YytPmsSkuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("inventory", 0).in("spu_id", list);
        return ResponseResult.success(yytPmsSkuInfoService.list(queryWrapper));
    }



}
